package com.ld.security.common.activiti.core;

import com.ld.security.common.activiti.core.po.*;
import com.ld.security.common.activiti.core.vo.*;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskInfo;
import org.activiti.engine.task.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public abstract class BaseFlowServiceImpl implements BaseFlowService {

    @Autowired
    protected RepositoryService repositoryService;

    @Autowired
    protected RuntimeService runtimeService;

    @Autowired
    protected  TaskService taskService;

    @Autowired
    HistoryService historyService;

    @Override
    public String startFlow(StartFlowPo po) {
        Map map = po.getArgs();
        // 启动并获取流程实例
        ProcessInstance processInstance=runtimeService// 运行时流程实例Service

                .startProcessInstanceByKey(this.getProcessInstanceByKey(),map); // 流程定义表的KEY字段值



        return processInstance.getId();
    }

    @Override
    public FlowPageVo flowPage(FlowPagePo po) {
        ProcessInstanceQuery query =  runtimeService.createProcessInstanceQuery()
                .processDefinitionKey(this.getProcessInstanceByKey());
        if(po.getFlowName() != null){
            query.processInstanceNameLike(po.getFlowName());
        }
        if(po.getProcessInstanceId() != null){
            query.processInstanceId(po.getProcessInstanceId());
        }

        List<ProcessInstance> list=      query.listPage(po.getPageNumber(),po.getPageSize());
        int total =(int)  query.count();
        FlowPageVo vo =toFlowPageVo(list);
        vo.setTotal(total);
        return vo;
    }



    @Override
    public FlowPageVo hiFlowPage(FlowPagePo po) {

        HistoricProcessInstanceQuery query =  historyService.createHistoricProcessInstanceQuery();

        query.processDefinitionKey(this.getProcessInstanceByKey());
        if(po.getFlowName() != null){
            query.processInstanceNameLike(po.getFlowName());
        }
        List<HistoricProcessInstance> list=      query.listPage(po.getPageNumber(),po.getPageSize());
        int total =(int)  query.count();

        FlowPageVo vo = new FlowPageVo();
        vo.setTotal(total);

        for (HistoricProcessInstance processInstance : list) {
            FlowVo v = new FlowVo();
            v.setName(    processInstance.getProcessDefinitionKey());
            v.setId( processInstance.getId());
            v.setCrtTime(    processInstance.getStartTime());
            vo.addItem(v);
        }



        return vo;
    }

    @Override
    public TaskPageVo taskPage(TaskPagePo po) {
        TaskQuery query =  taskService


                .createTaskQuery() ;

        if(po.getTaskName() != null){
            query.taskNameLike(po.getTaskName());
        }
        if(po.getRoleId() != null){
            query.taskInvolvedGroupsIn(po.getRoleId());
        }
        if(po.getProcessInstanceId() != null){
            query.processInstanceId(po.getProcessInstanceId());
        }
        if(po.getUserId() != null){
            query.taskAssignee(po.getUserId());
        }

        List<Task> list = query.listPage(po.getPageNumber(),po.getPageSize());
        int total = (int)query.count();

        TaskPageVo vo =toTaskPageVo(list);
        vo.setTotal(total);

        return vo;
    }




    /**
     *
     * @param po
     * @return
     */
    @Override
    public TaskPageVo hiTaskPage(TaskPagePo po) {
        HistoricTaskInstanceQuery query =  historyService.createHistoricTaskInstanceQuery();
        if(po.getTaskName() != null){
            query.taskNameLike(po.getTaskName());
        }
        if(po.getRoleId() != null){
            query.taskInvolvedGroupsIn(po.getRoleId());
        }
        if(po.getProcessInstanceId() != null){
            query.processInstanceId(po.getProcessInstanceId());
        }
        if(po.getUserId() != null){
            query.taskAssignee(po.getUserId());
        }
        List<HistoricTaskInstance> list  = query.listPage(po.getPageNumber(),po.getPageSize());
        int total = (int)query.count();
        TaskPageVo vo = toTaskPageVo(list);
        vo.setTotal(total);
        return vo;
    }

    @Override
    public void completeTask(CompleteTaskPo po) {

        if(po.getArgs() == null){
            taskService.complete(po.getTaksId());

        }else{
            taskService.complete(po.getTaksId(),po.getArgs());

        }

    }



    /**
     * 任务转换
     * @param list
     * @return
     */
    private TaskPageVo toTaskPageVo(List<? extends  TaskInfo> list){
        TaskPageVo vo = new TaskPageVo();

        for(TaskInfo task:list){
            TaskVo v =  new TaskVo();

            v.setId(task.getId());
            v.setCrtTime(task.getCreateTime());
            v.setFlowId(task.getProcessInstanceId());
            v.setName(task.getName());
            v.setUserId(task.getAssignee());
            vo.addItem(v);

        }
        return vo;
    }

    /**
     * 流程实例转换
     * @param list
     * @return
     */
    private FlowPageVo toFlowPageVo(List<ProcessInstance> list){
        FlowPageVo vo = new FlowPageVo();

        for (ProcessInstance processInstance : list) {
            FlowVo v = new FlowVo();
            v.setName(    processInstance.getProcessDefinitionKey());
            v.setId( processInstance.getId());
            v.setCrtTime(    processInstance.getStartTime());
            vo.addItem(v);
        }
        return vo;
    }




    @Override
    public void setTaskArgs(TaskArgsPo po) {
        if(po.isLocal()){
            taskService.setVariablesLocal(po.getTaskId(),po.getArgs());

        }else{
            taskService.setVariables(po.getTaskId(),po.getArgs());
        }
    }

    @Override
    public TaskArgsVo getTaskLocalArgs(String taskId) {
        Map localArgs =  taskService.getVariablesLocal(taskId);
        Map processArgs =  taskService.getVariables(taskId);

        TaskArgsVo vo =  new TaskArgsVo();
        vo.setLocalArgs(localArgs);
        vo.setProcessArgs(processArgs);
        return vo;
    }

    /**
     * 流程图里面的key
     * @return
     */
    protected  abstract String getProcessInstanceByKey();
}
